<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>人事管理系统</title>
  <!-- 引入Element Plus -->
  <link href="https://unpkg.com/element-plus/dist/index.css" rel="stylesheet">
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script src="https://unpkg.com/element-plus/dist/index.full.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <style>
    :root {
      --primary: #3498db;
      --admin: #e74c3c;
      --staff: #2ecc71;
      --late: #f39c12;
      --absent: #95a5a6;
      --present: #2ecc71;
      --overtime: #9b59b6;
    }
    * { box-sizing: border-box; font-family: 'Microsoft YaHei', sans-serif; }
    body { margin: 0; background: #f5f7fa; color: #333; }
    .app-container { max-width: 1200px; margin: 0 auto; padding: 20px; }
    
    /* 响应式设计 */
    @media (max-width: 768px) {
      .dashboard { grid-template-columns: 1fr; }
      .el-dialog { width: 95%!important; }
      .header { flex-direction: column; }
    }
    
    /* 公共组件样式 */
    .card { background: white; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); padding: 20px; margin-bottom: 20px; }
    .flex-center { display: flex; align-items: center; justify-content: center; }
    .text-center { text-align: center; }
    
    /* 权限标签 */
    .role-tag {
      padding: 3px 10px;
      border-radius: 4px;
      color: white;
      font-size: 12px;
      margin-left: 10px;
    }
    .admin-tag { background: var(--admin); }
    .staff-tag { background: var(--staff); }
    
    /* 考勤状态 */
    .status-present { color: var(--present); font-weight: bold; }
    .status-late { color: var(--late); font-weight: bold; }
    .status-absent { color: var(--absent); font-weight: bold; }
  </style>
</head>
<body>
  <div id="app">
    <!-- 登录页面 -->
    <div v-if="!isLoggedIn" class="app-container flex-center" style="height: 100vh;">
      <el-card class="login-card" style="width: 400px;">
        <template #header>
          <div class="text-center">
            <h2>人事管理系统</h2>
            <p>请输入账号密码登录系统</p>
          </div>
        </template>
        <el-form :model="loginForm" label-width="80px">
          <el-form-item label="用户名">
            <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
          </el-form-item>
          <el-form-item label="密码">
            <el-input v-model="loginForm.password" type="password" placeholder="请输入密码"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleLogin" style="width: 100%;">登录</el-button>
          </el-form-item>
        </el-form>
        <div v-if="loginError" class="el-alert el-alert--error">
          {{ loginError }}
        </div>
      </el-card>
    </div>

    <!-- 主系统界面 -->
    <div v-else>
      <!-- 顶部导航栏 -->
      <div class="header card" style="display: flex; justify-content: space-between; align-items: center;">
        <div class="menu">
          <el-button 
            v-for="item in permittedMenus" 
            :key="item.page"
            :type="activePage === item.page ? 'primary' : ''"
            @click="activePage = item.page"
          >
            {{ item.title }}
          </el-button>
        </div>
        <div class="user-info" style="display: flex; align-items: center;">
          <el-avatar :size="36" style="margin-right: 10px;">{{ currentUser.charAt(0) }}</el-avatar>
          <span>{{ currentUser }}</span>
          <span :class="['role-tag', currentRole === 'admin' ? 'admin-tag' : 'staff-tag']">
            {{ currentRole === 'admin' ? '管理员' : '员工' }}
          </span>
          <el-button type="text" @click="handleLogout" style="margin-left: 15px;">退出</el-button>
        </div>
      </div>

      <!-- 主内容区 -->
      <div class="main-content">
        <!-- 仪表盘 -->
        <div v-if="activePage === 'dashboard'" class="page">
          <h2>工作台 <small>欢迎回来，{{ currentUser }}</small></h2>
          
          <div class="dashboard" style="display: grid; grid-template-columns: 3fr 2fr; gap: 20px;">
            <!-- 考勤日历 -->
            <el-card class="panel">
              <template #header>
                <div style="display: flex; justify-content: space-between; align-items: center;">
                  <span>我的考勤日历 ({{ currentMonth }})</span>
                  <el-button type="text" @click="prevMonth">上个月</el-button>
                </div>
              </template>
              <div class="calendar" style="display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px;">
                <div v-for="day in calendarDays" :key="day.date" 
                     :class="['day', `status-${day.status}`]"
                     style="padding: 10px; text-align: center; border-radius: 4px; cursor: pointer;"
                     @click="showDayDetails(day)">
                  <div>{{ day.day }}</div>
                  <div>{{ getStatusIcon(day.status) }}</div>
                </div>
              </div>
            </el-card>
            
            <!-- 考勤统计 -->
            <el-card class="panel">
              <template #header>
                <span>考勤统计</span>
              </template>
              <el-descriptions :column="1" border>
                <el-descriptions-item label="本月出勤">
                  <el-tag type="success">{{ attendanceStats.workDays }} 天</el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="迟到次数">
                  <el-tag type="warning">{{ attendanceStats.lateDays }} 次</el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="加班时长">
                  <el-tag type="info">{{ attendanceStats.overtimeHours }} 小时</el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="预计薪资">
                  <el-tag type="primary">{{ salaryData.totalSalary }} 元</el-tag>
                </el-descriptions-item>
              </el-descriptions>
            </el-card>
          </div>
          
          <!-- 打卡状态提示 -->
          <el-alert v-if="!attendanceStatus.checkedIn" 
                   title="今日尚未打卡" 
                   type="error" 
                   :closable="false"
                   style="margin-top: 20px;">
            <el-button type="danger" size="small" @click="checkIn">立即打卡</el-button>
          </el-alert>
          <el-alert v-else-if="!attendanceStatus.checkedOut"
                   title="已上班打卡，尚未签退"
                   type="warning"
                   :closable="false"
                   style="margin-top: 20px;">
            <el-button type="warning" size="small" @click="checkOut">签退</el-button>
          </el-alert>
          <el-alert v-else
                   title="今日考勤已完成"
                   type="success"
                   :closable="false"
                   style="margin-top: 20px;">
          </el-alert>
        </div>

        <!-- 考勤管理 -->
        <div v-if="activePage === 'attendance'" class="page">
          <h2>考勤管理</h2>
          
          <!-- 实时打卡 -->
          <el-card class="attendance-card text-center" style="margin-bottom: 20px;">
            <div class="current-time" style="font-size: 2rem; margin: 15px 0; color: var(--primary); font-weight: bold;">
              {{ currentTime }}
            </div>
            <div style="margin: 20px 0;">
              <el-button 
                type="primary" 
                size="large" 
                @click="checkIn" 
                :disabled="attendanceStatus.checkedIn"
                style="width: 150px;"
              >
                {{ attendanceStatus.checkedIn ? '已打卡' : '上班打卡' }}
              </el-button>
              <el-button 
                type="warning" 
                size="large" 
                @click="checkOut" 
                :disabled="!attendanceStatus.checkedIn || attendanceStatus.checkedOut"
                style="width: 150px; margin-left: 20px;"
              >
                {{ attendanceStatus.checkedOut ? '已签退' : '下班签退' }}
              </el-button>
            </div>
          </el-card>
          
          <!-- 加班申请 -->
          <el-card class="overtime-section">
            <template #header>
              <div class="card-header">
                <span>加班申请</span>
              </div>
            </template>
            <el-form :model="overtimeForm" label-width="100px">
              <el-form-item label="加班时长">
                <el-input-number v-model="overtimeForm.hours" :min="0.5" :step="0.5" />
                <span style="margin-left: 10px;">小时</span>
              </el-form-item>
              <el-form-item label="加班原因">
                <el-input 
                  v-model="overtimeForm.reason" 
                  type="textarea" 
                  placeholder="请填写加班原因"
                  rows="3"
                ></el-input>
              </el-form-item>
              <el-form-item label="证明文件">
                <el-upload
                  action="/api/upload"
                  :before-upload="beforeUpload"
                  :on-success="handleUploadSuccess"
                  :limit="1"
                  accept=".pdf,.jpg,.png,.doc,.docx"
                >
                  <el-button type="primary">上传文件</el-button>
                  <template #tip>
                    <div class="el-upload__tip">支持格式：PDF/JPG/PNG/DOC，文件大小不超过10MB</div>
                  </template>
                </el-upload>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="submitOvertime">提交申请</el-button>
              </el-form-item>
            </el-form>
          </el-card>
          
          <!-- 考勤记录 -->
          <el-card style="margin-top: 20px;">
            <template #header>
              <span>考勤记录</span>
              <el-date-picker
                v-model="attendanceFilter.month"
                type="month"
                placeholder="选择月份"
                format="YYYY-MM"
                style="float: right; width: 150px;"
              />
            </template>
            <el-table :data="filteredAttendanceRecords" border height="400">
              <el-table-column prop="date" label="日期" width="140" />
              <el-table-column prop="checkIn" label="上班时间" width="120" />
              <el-table-column prop="checkOut" label="下班时间" width="120" />
              <el-table-column label="加班时长" width="100">
                <template #default="{row}">
                  <span v-if="row.overtime > 0" style="color: var(--overtime);">{{ row.overtime }} 小时</span>
                  <span v-else>-</span>
                </template>
              </el-table-column>
              <el-table-column label="状态">
                <template #default="{row}">
                  <el-tag :type="getStatusTagType(row.status)">
                    {{ getStatusText(row.status) }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="附件" width="120">
                <template #default="{row}">
                  <el-button v-if="row.attachment" type="text" @click="downloadFile(row.attachment)">下载</el-button>
                  <span v-else>-</span>
                </template>
              </el-table-column>
            </el-table>
          </el-card>
        </div>

        <!-- 薪酬管理 -->
        <div v-if="activePage === 'salary' && hasPermission('salary:view')" class="page">
          <h2>薪酬管理</h2>
          
          <el-card>
            <template #header>
              <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>薪资记录</span>
                <el-button type="primary" @click="exportSalary">导出报表</el-button>
              </div>
            </template>
            <el-table :data="salaryRecords" border style="width: 100%">
              <el-table-column prop="date" label="月份" width="120" />
              <el-table-column prop="baseSalary" label="基本工资" width="120" />
              <el-table-column prop="bonus" label="全勤奖" width="120" />
              <el-table-column prop="overtimePay" label="加班补贴" width="120" />
              <el-table-column label="实发工资" width="140">
                <template #default="{row}">
                  <el-tag type="success">{{ row.totalSalary }} 元</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="150">
                <template #default="{row}">
                  <el-button type="primary" size="small" @click="viewSalaryDetail(row)">详情</el-button>
                  <el-button size="small" @click="printSalary(row)">打印</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-card>
          
          <!-- 薪资详情弹窗 -->
          <el-dialog v-model="salaryDetailVisible" title="薪资详情" width="600px">
            <el-descriptions :column="1" border>
              <el-descriptions-item label="基本工资">{{ currentSalaryDetail.baseSalary }} 元</el-descriptions-item>
              <el-descriptions-item label="全勤奖">{{ currentSalaryDetail.bonus }} 元</el-descriptions-item>
              <el-descriptions-item label="加班补贴">{{ currentSalaryDetail.overtimePay }} 元</el-descriptions-item>
              <el-descriptions-item label="应发工资">
                <span style="font-weight: bold; font-size: 1.2rem; color: var(--primary);">
                  {{ currentSalaryDetail.totalSalary }} 元
                </span>
              </el-descriptions-item>
            </el-descriptions>
            <template #footer>
              <el-button @click="salaryDetailVisible = false">关闭</el-button>
            </template>
          </el-dialog>
        </div>
      </div>
    </div>
  </div>

  <script>
    const { createApp, ref, computed, onMounted, watch } = Vue;
    const { ElMessage, ElNotification, ElLoading } = ElementPlus;

    const app = createApp({
      setup() {
        // 用户状态
        const isLoggedIn = ref(false);
        const loginForm = ref({ username: '', password: '' });
        const loginError = ref('');
        const currentUser = ref('');
        const currentRole = ref('staff');
        const apiBaseUrl = 'http://localhost:8080/api';
        
        // 页面导航
        const activePage = ref('dashboard');
        const menuItems = [
          { page: 'dashboard', title: '工作台', perm: 'dashboard:view' },
          { page: 'attendance', title: '考勤管理', perm: 'attendance:*' },
          { page: 'salary', title: '薪酬管理', perm: 'salary:view' },
        ];
        
        // 权限控制
        const userPermissions = ref([]);
        const permittedMenus = computed(() => {
          return menuItems.filter(item => hasPermission(item.perm));
        });
        
        function hasPermission(permission) {
          if (currentRole.value === 'admin') return true;
          return userPermissions.value.includes(permission);
        }
        
        // 考勤状态
        const attendanceStatus = ref({
          checkedIn: false,
          checkedOut: false,
          lastCheckIn: null
        });
        
        const currentTime = ref('--:--:--');
        const attendanceStats = ref({
          workDays: 0,
          lateDays: 0,
          overtimeHours: 0
        });
        
        // 考勤记录
        const attendanceRecords = ref([]);
        const attendanceFilter = ref({
          month: new Date().toISOString().slice(0, 7)
        });
        
        // 日历数据
        const calendarDays = ref([]);
        const currentMonth = ref('');
        
        // 薪酬数据
        const salaryData = ref({
          baseSalary: 0,
          bonus: 0,
          overtimePay: 0,
          totalSalary: 0
        });
        
        const salaryRecords = ref([]);
        const salaryDetailVisible = ref(false);
        const currentSalaryDetail = ref({});
        
        // 加班申请
        const overtimeForm = ref({
          hours: 0,
          reason: '',
          attachment: null
        });
        
        // 初始化日历
        function initCalendar() {
          const now = new Date();
          const year = now.getFullYear();
          const month = now.getMonth();
          currentMonth.value = `${year}年${month + 1}月`;
          
          const daysInMonth = new Date(year, month + 1, 0).getDate();
          const days = [];
          
          for (let i = 1; i <= daysInMonth; i++) {
            const date = new Date(year, month, i);
            const dayOfWeek = date.getDay();
            const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
            const status = isWeekend ? 'absent' : 'present';
            
            days.push({
              day: i,
              date: `${year}-${String(month + 1).padStart(2, '0')}-${String(i).padStart(2, '0')}`,
              status: status,
              workHours: status === 'present' ? 8 : 0,
              overtime: 0
            });
          }
          
          calendarDays.value = days;
          updateAttendanceStats();
        }
        
        // 更新考勤统计
        function updateAttendanceStats() {
          const stats = { workDays: 0, lateDays: 0, overtimeHours: 0 };
          
          attendanceRecords.value.forEach(record => {
            if (record.status !== 'absent') stats.workDays++;
            if (record.status === 'late') stats.lateDays++;
            if (record.overtime > 0) stats.overtimeHours += record.overtime;
          });
          
          attendanceStats.value = stats;
        }
        
        // 获取当前时间
        function updateCurrentTime() {
          const now = new Date();
          currentTime.value = now.toLocaleTimeString();
        }
        
        // 登录处理
        async function handleLogin() {
          const loading = ElLoading.service({
            lock: true,
            text: '登录中...',
            background: 'rgba(0, 0, 0, 0.7)'
          });
          
          try {
            const response = await axios.post(`${apiBaseUrl}/login`, {
              username: loginForm.value.username,
              password: loginForm.value.password
            });
            
            if (response.data && response.data.success) {
              isLoggedIn.value = true;
              currentUser.value = loginForm.value.username;
              currentRole.value = response.data.role || 'staff';
              
              // 初始化页面数据
              initCalendar();
              loadAttendance();
              loadSalary();
              setInterval(updateCurrentTime, 1000);
              
              ElNotification.success({
                title: '登录成功',
                message: `欢迎回来，${currentUser.value}`
              });
            } else {
              loginError.value = response.data.message || '用户名或密码错误';
            }
          } catch (error) {
            console.error('登录失败:', error);
            loginError.value = '登录请求失败，请检查网络连接';
          } finally {
            loading.close();
          }
        }
        
        // 退出登录
        function handleLogout() {
          isLoggedIn.value = false;
          currentUser.value = '';
          currentRole.value = 'staff';
          loginForm.value = { username: '', password: '' };
        }
        
        // 考勤操作
        async function checkIn() {
          try {
            const response = await axios.post(`${apiBaseUrl}/checkin`);
            if (response.data.success) {
              attendanceStatus.value.checkedIn = true;
              attendanceStatus.value.lastCheckIn = new Date();
              ElMessage.success('打卡成功！');
              loadAttendance();
            }
          } catch (error) {
            ElMessage.error('打卡失败：' + error.message);
          }
        }
        
        async function checkOut() {
          if (!attendanceStatus.value.checkedIn) {
            ElMessage.error('请先打卡上班');
            return;
          }
          
          try {
            const response = await axios.post(`${apiBaseUrl}/checkout`);
            if (response.data.success) {
              attendanceStatus.value.checkedOut = true;
              ElMessage.success('签退成功！');
              loadAttendance();
            }
          } catch (error) {
            ElMessage.error('签退失败：' + error.message);
          }
        }
        
        // 加班申请
        async function submitOvertime() {
          if (overtimeForm.value.hours <= 0) {
            ElMessage.error('请输入有效的加班时长');
            return;
          }
          
          try {
            const response = await axios.post(`${apiBaseUrl}/overtime`, {
              minutes: Math.round(overtimeForm.value.hours * 60)
            });
            
            if (response.data.success) {
              ElMessage.success('加班申请已提交');
              overtimeForm.value = { hours: 0, reason: '', attachment: null };
              loadAttendance();
            }
          } catch (error) {
            ElMessage.error('提交失败：' + error.message);
          }
        }
        
        // 加载考勤数据
        async function loadAttendance() {
          try {
            const response = await axios.get(`${apiBaseUrl}/attendance`);
            if (response.data) {
              attendanceRecords.value = response.data;
              updateAttendanceStats();
              updateCalendarStatus();
            }
          } catch (error) {
            console.error('加载考勤数据失败:', error);
          }
        }
        
        // 加载薪资数据
        async function loadSalary() {
          try {
            const response = await axios.get(`${apiBaseUrl}/salary`);
            if (response.data && response.data.salary) {
              salaryData.value = {
                baseSalary: response.data.salary * 0.7,
                bonus: response.data.salary * 0.1,
                overtimePay: response.data.salary * 0.2,
                totalSalary: response.data.salary
              };
            }
            
            // 模拟历史工资记录
            salaryRecords.value = [
              { date: '2025-05', ...salaryData.value },
              { 
                date: '2025-04', 
                baseSalary: 7500, 
                bonus: 500,
                overtimePay: 1200,
                totalSalary: 9200
              },
              { 
                date: '2025-03', 
                baseSalary: 7500, 
                bonus: 700,
                overtimePay: 800,
                totalSalary: 9000
              }
            ];
          } catch (error) {
            console.error('加载薪资数据失败:', error);
          }
        }
        
        // 文件上传处理
        function beforeUpload(file) {
          const validTypes = [
            'application/pdf',
            'image/jpeg',
            'image/png',
            'application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
          ];
          
          const isValidType = validTypes.includes(file.type);
          const isValidSize = file.size / 1024 / 1024 < 10;
          
          if (!isValidType) {
            ElMessage.error('只能上传 PDF/JPG/PNG/DOC 格式文件!');
            return false;
          }
          
          if (!isValidSize) {
            ElMessage.error('文件大小不能超过 10MB!');
            return false;
          }
          
          return true;
        }
        
        function handleUploadSuccess(response) {
          overtimeForm.value.attachment = response.filePath;
          ElMessage.success('文件上传成功');
        }
        
        // 状态文本转换
        function getStatusText(status) {
          switch(status) {
            case 'present': return '正常出勤';
            case 'late': return '迟到';
            case 'absent': return '缺勤';
            default: return status;
          }
        }
        
        function getStatusTagType(status) {
          switch(status) {
            case 'present': return 'success';
            case 'late': return 'warning';
            case 'absent': return 'danger';
            default: return 'info';
          }
        }
        
        function getStatusIcon(status) {
          switch(status) {
            case 'present': return '✓';
            case 'late': return '!';
            case 'absent': return '✗';
            default: return '';
          }
        }
        
        // 薪资详情查看
        function viewSalaryDetail(row) {
          currentSalaryDetail.value = row;
          salaryDetailVisible.value = true;
        }
        
        // 薪资打印
        function printSalary(row) {
          ElMessage.info('打印功能需连接打印机');
        }
        
        // 导出薪资报表
        function exportSalary() {
          ElMessage.success('薪资报表已导出为Excel文件');
        }
        
        // 文件下载
        function downloadFile(filename) {
          ElMessage.info(`下载文件: ${filename}`);
        }
        
        // 日期详情查看
        function showDayDetails(day) {
          const record = attendanceRecords.value.find(r => r.date === day.date);
          
          if (record) {
            ElMessage.info(`日期: ${day.date} | 状态: ${getStatusText(day.status)} | 工时: ${record.workHours || 0}小时`);
          } else {
            ElMessage.info(`日期: ${day.date} | 状态: ${getStatusText(day.status)}`);
          }
        }
        
        // 更新日历状态
        function updateCalendarStatus() {
          calendarDays.value.forEach(day => {
            const record = attendanceRecords.value.find(r => r.date === day.date);
            if (record) {
              day.status = record.status;
              day.overtime = record.overtime;
            }
          });
        }
        
        // 上个月
        function prevMonth() {
          const [year, month] = currentMonth.value.split('年');
          let prevYear = parseInt(year);
          let prevMonth = parseInt(month) - 1;
          
          if (prevMonth === 0) {
            prevYear--;
            prevMonth = 12;
          }
          
          currentMonth.value = `${prevYear}年${prevMonth}月`;
          attendanceFilter.value.month = `${prevYear}-${String(prevMonth).padStart(2, '0')}`;
          // 实际项目中这里应该重新加载对应月份的数据
        }
        
        // 过滤后的考勤记录
        const filteredAttendanceRecords = computed(() => {
          return attendanceRecords.value.filter(record => {
            return record.date.startsWith(attendanceFilter.value.month);
          });
        });
        
        // 监听考勤过滤变化
        watch(attendanceFilter, () => {
          loadAttendance();
        }, { deep: true });
        
        // 初始化更新时间
        updateCurrentTime();
        
        return {
          isLoggedIn,
          loginForm,
          loginError,
          currentUser,
          currentRole,
          activePage,
          permittedMenus,
          attendanceStatus,
          currentTime,
          attendanceStats,
          calendarDays,
          currentMonth,
          salaryData,
          salaryRecords,
          overtimeForm,
          attendanceRecords,
          attendanceFilter,
          filteredAttendanceRecords,
          salaryDetailVisible,
          currentSalaryDetail,
          hasPermission,
          handleLogin,
          handleLogout,
          checkIn,
          checkOut,
          submitOvertime,
          beforeUpload,
          handleUploadSuccess,
          getStatusText,
          getStatusTagType,
          getStatusIcon,
          viewSalaryDetail,
          printSalary,
          exportSalary,
          downloadFile,
          showDayDetails,
          prevMonth
        };
      }
    });

    app.use(ElementPlus);
    app.mount('#app');
  </script>
</body>
</html>